<!-- <template>
  <div class="app-container">
    <el-form
      :model="queryParams"
      ref="queryForm"
      size="small"
      :inline="true"
      v-show="showSearch"
    >
      <el-form-item label="角色名称" prop="roleName">
        <el-input
          v-model="queryParams.roleName"
          placeholder="请输入角色名称"
          clearable
          maxlength="10"
          show-word-limit
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          icon="el-icon-search"
          size="mini"
          @click="handleQuery"
          >搜索</el-button
        >
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
          >重置</el-button
        >
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['product:roleField:add']"
          >新增</el-button
        >
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['product:roleField:remove']"
          >删除</el-button
        >
      </el-col>
      <right-toolbar
        :showSearch.sync="showSearch"
        @queryTable="getList"
      ></right-toolbar>
    </el-row>

    <el-table
      v-loading="loading"
      :data="roleFieldList"
      @selection-change="handleSelectionChange"
      border
      stripe
    >
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="序号" align="center" width="55" type="index" />
      <el-table-column label="角色名称" align="center" prop="roleName" />
      <el-table-column label="字段名" align="center" prop="fieldName" />
      <el-table-column label="备注" align="center" prop="remark" />
      <el-table-column
        label="操作"
        align="center"
        class-name="small-padding fixed-width"
        fixed="right"
        width="120"
      >
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['product:roleField:edit']"
            >修改</el-button
          >
          <el-button
            size="mini"
            type="text"
            @click="handleDelete(scope.row)"
            v-hasPermi="['product:roleField:remove']"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <el-dialog
      :title="title"
      :visible.sync="open"
      width="800px"
      append-to-body
      :close-on-click-modal="false"
    >
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="角色" prop="roleId">
          <el-select v-model="form.roleId" @change="getRoleName">
            <el-option
              v-for="item in roleDatas"
              :key="item.roleId"
              :label="item.roleName"
              :value="item.roleId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="字段名" prop="fieldList">
          <el-select
            v-model="selectedFields"
            multiple
            style="width: 100%"
            @change="handleFieldSelection"
            @remove-tag="handleRemoveTag"
          >
            <el-option
              v-for="item in availableFields"
              :key="item.field"
              :label="item.label"
              :value="item.field"

            />
          </el-select>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
            v-model="form.remark"
            type="textarea"
            placeholder="请输入内容"
            rows="3"
            maxlength="100"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  listRoleField,
  getRoleField,
  delRoleField,
  addRoleField,
  updateRoleField,
  roleList,
  fieldMap,
  fieldDefinition
} from "@/api/system/roleSetting";

export default {
  name: "RoleField",
  data() {
    return {
      // 原有数据属性保持不变
      loading: true,
      ids: [],
      single: true,
      multiple: true,
      showSearch: true,
      total: 0,
      roleFieldList: [],
      title: "",
      open: false,
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        roleId: null,
        roleName: null,
        field: null,
      },
      form: {},
      rules: {
        roleId: [{ required: true, message: "角色不能为空", trigger: "blur" }],
      },
      roleDatas: [],

      // 修改部分：字段选择相关数据
      selectedFields: [], // 已选中的字段（保持原始顺序）
      availableFields: [], // 所有可选的字段（保持固定原始顺序）
    };
  },
  created() {
    this.getList();
    this.initRoleDatas();
    this.initAvailableFields();
  },
  methods: {
    // 原有方法保持不变
    getList() {
      this.loading = true;
      listRoleField(this.queryParams).then((response) => {
        this.roleFieldList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.id);
      this.single = selection.length !== 1;
      this.multiple = !selection.length;
    },
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加角色字段";
    },
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal
        .confirm("是否确认删除角色字段数据项？")
        .then(function () {
          return delRoleField(ids);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {});
    },
    handleExport() {
      this.download(
        "product/roleField/export",
        {
          ...this.queryParams,
        },
        `roleField_${new Date().getTime()}.xlsx`
      );
    },
    submitForm() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          this.updateFormFields();
          if (this.form.id != null) {
            updateRoleField(this.form).then((response) => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addRoleField(this.form).then((response) => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    cancel() {
      this.open = false;
      this.reset();
    },
    reset() {
      this.form = {
        id: null,
        roleId: null,
        roleName: null,
        field: null,
        fieldName: null,
        remark: null
      };
      this.selectedFields = [];
    },
    getRoleName(roleId) {
      const role = this.roleDatas.find(item => item.roleId === roleId);
      if (role) {
        this.form.roleName = role.roleName;
      }
    },

    // 修改部分：字段选择相关方法
    initAvailableFields() {
      fieldMap().then((res) => {
        // 保持原始顺序不变
        this.availableFields = res.rows.map(item => ({
          field: item.field,
          label: item.label,
          sort: item.sort || 0 // 确保有排序字段
        })).sort((a, b) => a.sort - b.sort);
      });
    },

    initRoleDatas() {
      roleList().then((res) => {
        this.roleDatas = res.rows;
      });
    },

    handleFieldSelection(newSelected) {
      // 按照availableFields的原始顺序重新排序选中的字段
      this.selectedFields = this.availableFields
        .filter(item => newSelected.includes(item.field))
        .map(item => item.field);

      this.updateFormFields();
    },

    handleRemoveTag(removedTag) {
      this.selectedFields = this.selectedFields.filter(f => f !== removedTag);
      this.updateFormFields();
    },

    removeSelectedField(field) {
      this.selectedFields = this.selectedFields.filter(f => f !== field);
      this.updateFormFields();
    },

    updateFormFields() {
      this.form.field = this.selectedFields.join(',');
      this.form.fieldName = this.selectedFields
        .map(field => this.getFieldLabel(field))
        .join(',');
    },

    getFieldLabel(field) {
      const item = this.availableFields.find(f => f.field === field);
      return item ? item.label : field;
    },

    isFieldSelected(field) {
      return this.selectedFields.includes(field);
    },

    handleUpdate(row) {
      this.reset();
      const id = row.id || this.ids;
      getRoleField(id).then((response) => {
        this.form = response.data;
        if (response.data.field) {
          // 初始化时也按照原始顺序排序
          const selected = response.data.field.split(',');
          this.selectedFields = this.availableFields
            .filter(item => selected.includes(item.field))
            .map(item => item.field);
        }
        this.open = true;
        this.title = "修改角色字段";
      });
    }
  }
};
</script>

<style scoped>
/* 新增样式 */
.selected-fields-container {
  margin-top: 10px;
  padding: 10px;
  background: #f5f7fa;
  border-radius: 4px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.selected-field-item {
  display: inline-flex;
}
</style> -->

<template>
  <div class="app-container">
    <!-- 搜索表单部分 -->
    <el-form
      :model="queryParams"
      ref="queryForm"
      size="small"
      :inline="true"
      v-show="showSearch"
    >
      <el-form-item label="角色名称" prop="roleName">
        <el-input
          v-model="queryParams.roleName"
          placeholder="请输入角色名称"
          clearable
          maxlength="10"
          show-word-limit
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          icon="el-icon-search"
          size="mini"
          @click="handleQuery"
          >搜索</el-button
        >
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
          >重置</el-button
        >
      </el-form-item>
    </el-form>

    <!-- 操作按钮部分 -->
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['product:roleField:add']"
          >新增</el-button
        >
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['product:roleField:remove']"
          >删除</el-button
        >
      </el-col>
      <right-toolbar
        :showSearch.sync="showSearch"
        @queryTable="getList"
      ></right-toolbar>
    </el-row>

    <!-- 表格部分 -->
    <el-table
      v-loading="loading"
      :data="roleFieldList"
      @selection-change="handleSelectionChange"
      border
      stripe
    >
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="序号" align="center" width="55" type="index" />
      <el-table-column label="角色名称" align="center" prop="roleName" />
      <el-table-column label="字段名" align="center" prop="fieldName" />
      <el-table-column label="备注" align="center" prop="remark" />
      <el-table-column
        label="操作"
        align="center"
        class-name="small-padding fixed-width"
        fixed="right"
        width="120"
      >
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['product:roleField:edit']"
            >修改</el-button
          >
          <el-button
            size="mini"
            type="text"
            @click="handleDelete(scope.row)"
            v-hasPermi="['product:roleField:remove']"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页部分 -->
    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 对话框部分 - 使用自定义拖拽实现 -->
    <el-dialog
      :title="title"
      :visible.sync="open"
      width="900px"
      append-to-body
      v-dialogDrag
      :close-on-click-modal="false"
    >
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="角色" prop="roleId">
          <el-select v-model="form.roleId" @change="getRoleName">
            <el-option
              v-for="item in roleDatas"
              :key="item.roleId"
              :label="item.roleName"
              :value="item.roleId"
            ></el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="字段名" prop="fieldList">
          <div class="field-selector-container">
            <!-- 可选字段列表 -->
            <div class="available-fields">
              <div>可选字段</div>
              <div class="field-list">
                <div
                  v-for="item in availableFields"
                  :key="item.field"
                  class="field-item"
                  @click="addField(item)"
                >
                  {{ item.label }}
                </div>
              </div>
            </div>

            <!-- 已选字段列表（可拖动排序） -->
            <div class="selected-fields">
              <div>已选字段（拖动可排序）</div>
              <div class="field-list">
                <div
                  v-for="(item, index) in selectedFields"
                  :key="item.field"
                  class="field-item selected"
                  draggable="true"
                  @dragstart="dragStart(index)"
                  @dragover.prevent="dragOver(index)"
                  @dragenter="dragEnter(index)"
                  @dragend="dragEnd"
                  @drop="drop(index)"
                >
                  {{ item.label }}
                  <i class="el-icon-close" @click.stop="removeField(index)"></i>
                </div>
              </div>
            </div>
          </div>
        </el-form-item>

        <el-form-item label="备注" prop="remark">
          <el-input
            v-model="form.remark"
            type="textarea"
            placeholder="请输入内容"
            rows="3"
            maxlength="100"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  listRoleField,
  getRoleField,
  delRoleField,
  addRoleField,
  updateRoleField,
  roleList,
  fieldMap,
} from "@/api/system/roleSetting";

export default {
  name: "RoleField",
  data() {
    return {
      loading: true,
      ids: [],
      single: true,
      multiple: true,
      showSearch: true,
      total: 0,
      roleFieldList: [],
      title: "",
      open: false,
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        roleId: null,
        roleName: null,
        field: null,
      },
      form: {},
      rules: {
        roleId: [{ required: true, message: "角色不能为空", trigger: "blur" }],
      },
      roleDatas: [],
      allFields: [], // 所有字段数据
      selectedFields: [], // 已选字段数组
      draggedItem: null, // 当前拖拽的字段
      draggedIndex: null, // 当前拖拽的索引
    };
  },
  computed: {
    // 可用字段 = 所有字段 - 已选字段
    availableFields() {
      return this.allFields.filter(
        (field) => !this.selectedFields.some((f) => f.field === field.field)
      );
    },
  },
  created() {
    this.getList();
    this.initRoleDatas();
    this.initAvailableFields();
  },
  methods: {
    // 拖拽相关方法
    dragStart(index) {
      this.draggedIndex = index;
      this.draggedItem = this.selectedFields[index];
    },
    dragOver(index) {
      // 防止默认行为以允许drop
      event.preventDefault();
    },
    dragEnter(index) {
      if (this.draggedIndex !== index) {
        // 实时预览效果
        const newItems = [...this.selectedFields];
        newItems.splice(this.draggedIndex, 1);
        newItems.splice(index, 0, this.draggedItem);
        this.selectedFields = newItems;
        this.draggedIndex = index;
      }
    },
    dragEnd() {
      this.draggedItem = null;
      this.draggedIndex = null;
      this.updateFormFields();
    },
    drop(index) {
      if (this.draggedIndex !== index) {
        const newItems = [...this.selectedFields];
        newItems.splice(this.draggedIndex, 1);
        newItems.splice(index, 0, this.draggedItem);
        this.selectedFields = newItems;
        this.updateFormFields();
      }
    },

    // 字段操作方法
    addField(field) {
      this.selectedFields.push({ ...field });
      this.updateFormFields();
    },
    removeField(index) {
      this.selectedFields.splice(index, 1);
      this.updateFormFields();
    },

    // 初始化可用字段
    initAvailableFields() {
      fieldMap().then((res) => {
        // Store the original order from the API
        this.allFields = res.rows.map((item) => ({
          field: item.field,
          label: item.label,
          sort: item.sort || 0,
        }));

        // Sort by the original sort order if needed
        this.allFields.sort((a, b) => a.sort - b.sort);
        this.selectedFields = [];
      });
    },

    // 初始化角色数据
    initRoleDatas() {
      roleList().then((res) => {
        this.roleDatas = res.rows;
      });
    },

    // 更新表单字段数据
    updateFormFields() {
      this.form.field = this.selectedFields.map((f) => f.field).join(",");
      this.form.fieldName = this.selectedFields.map((f) => f.label).join(",");
    },

    // 获取角色名称
    getRoleName(roleId) {
      const role = this.roleDatas.find((item) => item.roleId === roleId);
      if (role) {
        this.form.roleName = role.roleName;
      }
    },

    // 查询列表
    getList() {
      this.loading = true;
      listRoleField(this.queryParams).then((response) => {
        this.roleFieldList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    handleUpdate(row) {
      this.reset();
      const id = row.id || this.ids;
      getRoleField(id).then((response) => {
        this.form = response.data;
        if (response.data.field) {
          const selectedFieldNames = response.data.field.split(",");
          const selectedFieldLabels = response.data.fieldName.split(",");
          const fieldMap = {};
          this.allFields.forEach((field) => {
            fieldMap[field.field] = field;
          });

          this.selectedFields = selectedFieldNames.map((fieldName, index) => {
            if (fieldMap[fieldName]) {
              return fieldMap[fieldName];
            }
            return {
              field: fieldName,
              label: selectedFieldLabels[index] || fieldName,
            };
          });
        }
        this.open = true;
        this.title = "修改角色字段";
      });
    },
    // 提交表单
    submitForm() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          this.updateFormFields();
          if (this.form.id != null) {
            updateRoleField(this.form).then((response) => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addRoleField(this.form).then((response) => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },

    // 重置表单
    reset() {
      this.form = {
        id: null,
        roleId: null,
        roleName: null,
        field: null,
        fieldName: null,
        remark: null,
      };
      this.selectedFields = [];
    },

    // 其他原有方法保持不变...
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.id);
      this.single = selection.length !== 1;
      this.multiple = !selection.length;
    },
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加角色字段";
    },
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal
        .confirm("是否确认删除角色字段数据项？")
        .then(function () {
          return delRoleField(ids);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {});
    },
    handleExport() {
      this.download(
        "product/roleField/export",
        {
          ...this.queryParams,
        },
        `roleField_${new Date().getTime()}.xlsx`
      );
    },
    cancel() {
      this.open = false;
      this.reset();
    },
  },
};
</script>

<style scoped>
.field-selector-container {
  display: flex;
  gap: 20px;
  height: 400px;
}

.available-fields,
.selected-fields {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.field-list {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 10px;
  height: 350px;
  overflow-y: auto;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 8px;
}

.field-item {
  padding: 0px 12px;
  margin: 0;
  background: #f5f7fa;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
  user-select: none;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
}

.field-item.selected {
  background: #ecf5ff;
  border: 1px solid #d9ecff;
  color: #409eff;
  position: relative;
  padding-right: 25px;
}

.field-item:hover {
  background: #ebeef5;
}

.field-item .el-icon-close {
  margin-left: 5px;
  color: #f56c6c;
  cursor: pointer;
  position: absolute;
  right: 5px;
}

/* 拖拽样式 */
.field-item.selected.dragging {
  opacity: 0.5;
  background: #c8ebfb;
}

/* 标题样式 */
.available-fields > div:first-child,
.selected-fields > div:first-child {
  font-weight: bold;
  margin-bottom: 8px;
  color: #606266;
}
</style>
